home *** CD-ROM | disk | FTP | other *** search
- # Source Generated with Decompyle++
- # File: in.pyc (Python 2.2)
-
- '''Manages the cache of generated Python code.
-
- Description
- This file manages the cache of generated Python code. When run from the
- command line, it also provides a number of options for managing that cache.
-
- Implementation
- Each typelib is generated into a filename of format "{guid}x{lcid}x{major}x{minor}.py"
-
- An external persistant dictionary maps from all known IIDs in all known type libraries
- to the type library itself.
-
- Thus, whenever Python code knows the IID of an object, it can find the IID, LCID and version of
- the type library which supports it. Given this information, it can find the Python module
- with the support.
-
- If necessary, this support can be generated on the fly.
-
- Hacks, to do, etc
- Currently just uses a pickled dictionary, but should used some sort of indexed file.
- Maybe an OLE2 compound file, or a bsddb file?
- '''
- import pywintypes
- import os
- import string
- import sys
- import pythoncom
- import win32com
- import win32com.client as win32com
- import glob
- import traceback
- import CLSIDToClass
- clsidToTypelib = { }
- demandGeneratedTypeLibraries = { }
-
- def __init__():
-
- try:
- _LoadDicts()
- except IOError:
- Rebuild()
-
-
- pickleVersion = 1
-
- def _SaveDicts():
- import cPickle
- f = open(os.path.join(GetGeneratePath(), 'dicts.dat'), 'wb')
-
- try:
- p = cPickle.Pickler(f)
- p.dump(pickleVersion)
- p.dump(clsidToTypelib)
- finally:
- f.close()
-
-
-
- def _LoadDicts():
- global clsidToTypelib
- import cPickle
-
- try:
- f = open(os.path.join(win32com.__gen_path__, 'dicts.dat'), 'rb')
- except AttributeError:
- return None
-
-
- try:
- p = cPickle.Unpickler(f)
- version = p.load()
- clsidToTypelib = p.load()
- finally:
- f.close()
-
-
-
- def GetGeneratedFileName(clsid, lcid, major, minor):
- '''Given the clsid, lcid, major and minor for a type lib, return
- \tthe file name (no extension) providing this support.
- \t'''
- return string.upper(str(clsid))[1:-1] + 'x%sx%sx%s' % (lcid, major, minor)
-
-
- def SplitGeneratedFileName(fname):
- '''Reverse of GetGeneratedFileName()
- \t'''
- return tuple(string.split(fname, 'x', 4))
-
-
- def GetGeneratePath():
- '''Returns the name of the path to generate to.
- \tChecks the directory is OK.
- \t'''
-
- try:
- os.mkdir(win32com.__gen_path__)
- except os.error:
- pass
-
-
- try:
- fname = os.path.join(win32com.__gen_path__, '__init__.py')
- os.stat(fname)
- except os.error:
- f = open(fname, 'w')
- f.write('# Generated file - this directory may be deleted to reset the COM cache...\n')
- f.write('import win32com\n')
- f.write('if __path__[:-1] != win32com.__gen_path__: __path__.append(win32com.__gen_path__)\n')
- f.close()
-
- return win32com.__gen_path__
-
-
- def GetClassForProgID(progid):
- '''Get a Python class for a Program ID
- \t
- \tGiven a Program ID, return a Python class which wraps the COM object
- \t
- \tReturns the Python class, or None if no module is available.
- \t
- \tParams
- \tprogid -- A COM ProgramID or IID (eg, "Word.Application")
- \t'''
- clsid = pywintypes.IID(progid)
- return GetClassForCLSID(clsid)
-
-
- def GetClassForCLSID(clsid):
- '''Get a Python class for a CLSID
- \t
- \tGiven a CLSID, return a Python class which wraps the COM object
- \t
- \tReturns the Python class, or None if no module is available.
- \t
- \tParams
- \tclsid -- A COM CLSID (or string repr of one)
- \t'''
- clsid = str(clsid)
- if CLSIDToClass.HasClass(clsid):
- return CLSIDToClass.GetClass(clsid)
-
- mod = GetModuleForCLSID(clsid)
- if mod is None:
- return None
-
-
- try:
- return CLSIDToClass.GetClass(clsid)
- except KeyError:
- return None
-
-
-
- def GetModuleForProgID(progid):
- '''Get a Python module for a Program ID
- \t
- \tGiven a Program ID, return a Python module which contains the
- \tclass which wraps the COM object.
- \t
- \tReturns the Python module, or None if no module is available.
- \t
- \tParams
- \tprogid -- A COM ProgramID or IID (eg, "Word.Application")
- \t'''
-
- try:
- iid = pywintypes.IID(progid)
- except pywintypes.com_error:
- return None
-
- return GetModuleForCLSID(iid)
-
-
- def GetModuleForCLSID(clsid):
- '''Get a Python module for a CLSID
- \t
- \tGiven a CLSID, return a Python module which contains the
- \tclass which wraps the COM object.
- \t
- \tReturns the Python module, or None if no module is available.
- \t
- \tParams
- \tprogid -- A COM CLSID (ie, not the description)
- \t'''
- clsid_str = str(clsid)
-
- try:
- (typelibCLSID, lcid, major, minor) = clsidToTypelib[clsid_str]
- except KeyError:
- return None
-
- mod = GetModuleForTypelib(typelibCLSID, lcid, major, minor)
- if mod is not None:
- sub_mod = mod.CLSIDToPackageMap.get(clsid_str)
- if sub_mod is None:
- sub_mod = mod.VTablesToPackageMap.get(clsid_str)
-
- if sub_mod is not None:
- sub_mod_name = mod.__name__ + '.' + sub_mod
-
- try:
- __import__(sub_mod_name)
- except ImportError:
- info = (typelibCLSID, lcid, major, minor)
- if demandGeneratedTypeLibraries.has_key(info):
- info = demandGeneratedTypeLibraries[info]
-
- import makepy
- makepy.GenerateChildFromTypeLibSpec(sub_mod, info)
-
- mod = sys.modules[sub_mod_name]
-
-
- return mod
-
-
- def GetModuleForTypelib(typelibCLSID, lcid, major, minor):
- '''Get a Python module for a type library ID
- \t
- \tGiven the CLSID of a typelibrary, return an imported Python module,
- \telse None
- \t
- \tParams
- \ttypelibCLSID -- IID of the type library.
- \tmajor -- Integer major version.
- \tminor -- Integer minor version
- \tlcid -- Integer LCID for the library.
- \t'''
- modName = GetGeneratedFileName(typelibCLSID, lcid, major, minor)
- return _GetModule(modName)
-
-
- def MakeModuleForTypelib(typelibCLSID, lcid, major, minor, progressInstance = None, bGUIProgress = None, bForDemand = 0, bBuildHidden = 1):
- '''Generate support for a type library.
- \t
- \tGiven the IID, LCID and version information for a type library, generate
- \tand import the necessary support files.
- \t
- \tReturns the Python module. No exceptions are caught.
-
- \tParams
- \ttypelibCLSID -- IID of the type library.
- \tmajor -- Integer major version.
- \tminor -- Integer minor version.
- \tlcid -- Integer LCID for the library.
- \tprogressInstance -- Instance to use as progress indicator, or None to
- \t use the GUI progress bar.
- \t'''
- if bGUIProgress is not None:
- print "The 'bGuiProgress' param to 'MakeModuleForTypelib' is obsolete."
-
- import makepy
-
- try:
- makepy.GenerateFromTypeLibSpec((typelibCLSID, lcid, major, minor), progressInstance = progressInstance, bForDemand = bForDemand, bBuildHidden = bBuildHidden)
- except pywintypes.com_error:
- return None
-
- return GetModuleForTypelib(typelibCLSID, lcid, major, minor)
-
-
- def MakeModuleForTypelibInterface(typelib_ob, progressInstance = None, bForDemand = 0, bBuildHidden = 1):
- '''Generate support for a type library.
- \t
- \tGiven a PyITypeLib interface generate and import the necessary support files. This is useful
- \tfor getting makepy support for a typelibrary that is not registered - the caller can locate
- \tand load the type library itself, rather than relying on COM to find it.
- \t
- \tReturns the Python module.
-
- \tParams
- \ttypelib_ob -- The type library itself
- \tprogressInstance -- Instance to use as progress indicator, or None to
- \t use the GUI progress bar.
- \t'''
- import makepy
-
- try:
- makepy.GenerateFromTypeLibSpec(typelib_ob, progressInstance = progressInstance, bForDemand = bForDemand, bBuildHidden = bBuildHidden)
- except pywintypes.com_error:
- return None
-
- tla = typelib_ob.GetLibAttr()
- guid = tla[0]
- lcid = tla[1]
- major = tla[3]
- minor = tla[4]
- return GetModuleForTypelib(guid, lcid, major, minor)
-
-
- def EnsureModuleForTypelibInterface(typelib_ob, progressInstance = None, bForDemand = 0, bBuildHidden = 1):
- '''Check we have support for a type library, generating if not.
- \t
- \tGiven a PyITypeLib interface generate and import the necessary
- \tsupport files if necessary. This is useful for getting makepy support
- \tfor a typelibrary that is not registered - the caller can locate and
- \tload the type library itself, rather than relying on COM to find it.
- \t
- \tReturns the Python module.
-
- \tParams
- \ttypelib_ob -- The type library itself
- \tprogressInstance -- Instance to use as progress indicator, or None to
- \t use the GUI progress bar.
- \t'''
- tla = typelib_ob.GetLibAttr()
- guid = tla[0]
- lcid = tla[1]
- major = tla[3]
- minor = tla[4]
- if bForDemand:
- demandGeneratedTypeLibraries[(str(guid), lcid, major, minor)] = typelib_ob
-
-
- try:
- return GetModuleForTypelib(guid, lcid, major, minor)
- except ImportError:
- pass
-
- return MakeModuleForTypelibInterface(typelib_ob, progressInstance, bForDemand, bBuildHidden)
-
-
- def ForgetAboutTypelibInterface(typelib_ob):
- '''Drop any references to a typelib previously added with EnsureModuleForTypelibInterface and forDemand'''
- tla = typelib_ob.GetLibAttr()
- guid = tla[0]
- lcid = tla[1]
- major = tla[3]
- minor = tla[4]
- info = (str(guid), lcid, major, minor)
-
- try:
- del demandGeneratedTypeLibraries[info]
- except KeyError:
- print 'ForgetAboutTypelibInterface:: Warning - type library with info %s is not being remembered!' % (info,)
-
-
-
- def EnsureModule(typelibCLSID, lcid, major, minor, progressInstance = None, bValidateFile = 1, bForDemand = 0, bBuildHidden = 1):
- '''Ensure Python support is loaded for a type library, generating if necessary.
- \t
- \tGiven the IID, LCID and version information for a type library, check and if
- \tnecessary (re)generate, then import the necessary support files. If we regenerate the file, there
- \tis no way to totally snuff out all instances of the old module in Python, and thus we will regenerate the file more than necessary,
- \tunless makepy/genpy is modified accordingly.
- \t
- \t
- \tReturns the Python module. No exceptions are caught during the generate process.
-
- \tParams
- \ttypelibCLSID -- IID of the type library.
- \tmajor -- Integer major version.
- \tminor -- Integer minor version
- \tlcid -- Integer LCID for the library.
- \tprogressInstance -- Instance to use as progress indicator, or None to
- \t use the GUI progress bar.
- \tbValidateFile -- Whether or not to perform cache validation or not
- \tbForDemand -- Should a complete generation happen now, or on demand?
- \tbBuildHidden -- Should hidden members/attributes etc be generated?
- \t'''
- bReloadNeeded = 0
-
- try:
-
- try:
- module = GetModuleForTypelib(typelibCLSID, lcid, major, minor)
- except ImportError:
- tlbAttr = pythoncom.LoadRegTypeLib(typelibCLSID, major, minor, lcid).GetLibAttr()
-
- try:
- module = GetModuleForTypelib(typelibCLSID, tlbAttr[1], tlbAttr[3], tlbAttr[4])
- except ImportError:
- module = None
- minor = tlbAttr[4]
-
-
- if bValidateFile:
- filePathPrefix = '%s\\%s' % (GetGeneratePath(), GetGeneratedFileName(typelibCLSID, lcid, major, minor))
- filePath = filePathPrefix + '.py'
- filePathPyc = filePathPrefix + '.py'
- if __debug__:
- filePathPyc = filePathPyc + 'c'
- else:
- filePathPyc = filePathPyc + 'o'
- typLibPath = pythoncom.QueryPathOfRegTypeLib(typelibCLSID, major, minor, lcid)
- tlbAttributes = pythoncom.LoadRegTypeLib(typelibCLSID, major, minor, lcid).GetLibAttr()
- import genpy
- if module is not None and module.MinorVersion != tlbAttributes[4] or genpy.makepy_version != module.makepy_version:
-
- try:
- os.unlink(filePath)
- except os.error:
- pass
-
-
- try:
- os.unlink(filePathPyc)
- except os.error:
- pass
-
- if os.path.isdir(filePathPrefix):
- import shutil
- shutil.rmtree(filePathPrefix)
-
- minor = tlbAttributes[4]
- module = None
- bReloadNeeded = 1
- elif module is not None:
- minor = module.MinorVersion
- filePathPrefix = '%s\\%s' % (GetGeneratePath(), GetGeneratedFileName(typelibCLSID, lcid, major, minor))
- filePath = filePathPrefix + '.py'
- filePathPyc = filePathPrefix + '.pyc'
- fModTimeSet = 0
-
- try:
- pyModTime = os.stat(filePath)[8]
- fModTimeSet = 1
- except os.error:
- e = None
-
- try:
- pyModTime = os.stat(filePathPyc)[8]
- fModTimeSet = 1
- except os.error:
- e = None
-
-
- typLibModTime = os.stat(str(typLibPath[:-1]))[8]
- if fModTimeSet and typLibModTime > pyModTime:
- bReloadNeeded = 1
- module = None
-
-
- except (ImportError, os.error):
- module = None
-
- if module is None:
- module = MakeModuleForTypelib(typelibCLSID, lcid, major, minor, progressInstance, bForDemand = bForDemand, bBuildHidden = bBuildHidden)
- if bReloadNeeded:
- module = reload(module)
- AddModuleToCache(typelibCLSID, lcid, major, minor)
-
-
- return module
-
-
- def EnsureDispatch(prog_id, bForDemand = 1):
- '''Given a COM prog_id, return an object that is using makepy support, building if necessary'''
- disp = win32com.client.Dispatch(prog_id)
- if not disp.__dict__.get('CLSID'):
-
- try:
- ti = disp._oleobj_.GetTypeInfo()
- disp_clsid = ti.GetTypeAttr()[0]
- (tlb, index) = ti.GetContainingTypeLib()
- tla = tlb.GetLibAttr()
- mod = EnsureModule(tla[0], tla[1], tla[3], tla[4], bForDemand = bForDemand)
- GetModuleForCLSID(disp_clsid)
- import CLSIDToClass
- disp_class = CLSIDToClass.GetClass(str(disp_clsid))
- disp = disp_class(disp._oleobj_)
- except pythoncom.com_error:
- raise TypeError, 'This COM object can not automate the makepy process - please run makepy manually for this object'
-
-
- return disp
-
-
- def AddModuleToCache(typelibclsid, lcid, major, minor, verbose = 1, bFlushNow = 1):
- '''Add a newly generated file to the cache dictionary.
- \t'''
- fname = GetGeneratedFileName(typelibclsid, lcid, major, minor)
- mod = _GetModule(fname)
- dict = mod.CLSIDToClassMap
- for clsid, cls in dict.items():
- clsidToTypelib[clsid] = (str(typelibclsid), mod.LCID, mod.MajorVersion, mod.MinorVersion)
-
- dict = mod.CLSIDToPackageMap
- for clsid, name in dict.items():
- clsidToTypelib[clsid] = (str(typelibclsid), mod.LCID, mod.MajorVersion, mod.MinorVersion)
-
- dict = mod.VTablesToClassMap
- for clsid, cls in dict.items():
- clsidToTypelib[clsid] = (str(typelibclsid), mod.LCID, mod.MajorVersion, mod.MinorVersion)
-
- dict = mod.VTablesToPackageMap
- for clsid, cls in dict.items():
- clsidToTypelib[clsid] = (str(typelibclsid), mod.LCID, mod.MajorVersion, mod.MinorVersion)
-
- if bFlushNow:
- _SaveDicts()
-
-
-
- def _GetModule(fname):
- '''Given the name of a module in the gen_py directory, import and return it.
- \t'''
- mod = __import__('win32com.gen_py.%s' % fname)
- return getattr(getattr(mod, 'gen_py'), fname)
-
-
- def Rebuild(verbose = 1):
- '''Rebuild the cache indexes from the file system.
- \t'''
- clsidToTypelib.clear()
- files = glob.glob(win32com.__gen_path__ + '\\*.py')
- if verbose and len(files):
- print 'Rebuilding cache of generated files for COM support...'
-
- for file in files:
- name = os.path.splitext(os.path.split(file)[1])[0]
-
- try:
- (iid, lcid, major, minor) = string.split(name, 'x')
- ok = 1
- except ValueError:
- ok = 0
-
- if ok:
-
- try:
- iid = pywintypes.IID('{' + iid + '}')
- except pywintypes.com_error:
- ok = 0
-
-
- if ok:
- if verbose:
- print 'Checking', name
-
-
- try:
- AddModuleToCache(iid, lcid, major, minor, verbose, 0)
- except:
- print 'Could not add module %s - %s: %s' % (name, sys.exc_info()[0], sys.exc_info()[1])
-
- elif verbose and name[0] != '_':
- print 'Skipping module', name
-
-
- if verbose and len(files):
- print 'Done.'
-
- _SaveDicts()
-
-
- def _Dump():
- print 'Cache is in directory', win32com.__gen_path__
- files = glob.glob(win32com.__gen_path__ + '\\*.py')
- for file in files:
- name = os.path.splitext(os.path.split(file)[1])[0]
- if name[0] != '_':
- mod = _GetModule(name)
- print '%s - %s' % (mod.__doc__, name)
-
-
-
- __init__()
- usageString = ' Usage: gencache [-q] [-d] [-r]\n \n -q - Quiet\n -d - Dump the cache (typelibrary description and filename).\n -r - Rebuild the cache dictionary from the existing .py files\n'
-
- def usage():
- print usageString
- sys.exit(1)
-
- if __name__ == '__main__':
- import getopt
-
- try:
- (opts, args) = getopt.getopt(sys.argv[1:], 'qrd')
- except getopt.error:
- message = None
- print message
- usage()
-
- if len(sys.argv) == 1 or args:
- print usage()
-
- verbose = 1
- for opt, val in opts:
- if opt == '-d':
- _Dump()
-
- if opt == '-r':
- Rebuild(verbose)
-
- if opt == '-q':
- verbose = 0
-
-
-
-